游戏开发中的AI (入门篇)
Unity正朝着AI的方向潜心探索着。本文是Unity发布的首篇AI相关文章,为大家介绍AI的一些概念及术语,详细介绍机器学习相关理论与方法,并讲解在使用Unity开发游戏的过程中如何应用AI。未来我们还将为大家分享更多AI的内容。
请点击[阅读原文]访问Unity官方中文社区(unitychina.cn),查看利用AI进行Unity游戏开发的实例工程,以及WebGL项目示例。
ML(机器学习)与 AI (人工智能)
首先来介绍下Machine Learning(机器学习,下文简称ML)和游戏Artificial Intelligence(人工智能,下文简称AI)间的关系。现存的大部分游戏AI都是手工编码,由大量决策树组成,有时会包含多达数千条规则。而且必须由手工维护和测试。而ML所依赖的算法可以自动从原始数据寻找规律,无需专家预先定义数据的解读方式。
以图片内容分类这个计算机视觉问题为例。直到几年前,专家们仍然通过手工编写过滤器,提取图像的有用特征,用于分辨某个图像中包含的是猫还是狗。而ML,特别是最新的深度学习方法,仅需图像和类型标签,就可以自动学习有用特征。我们相信这种自动化学习不仅可以拓展Unity平台的应用范围,例如用于ML场景模拟,还可以帮助所有开发者简化和加速游戏的开发过程。
这种自动化学习尤其可以应用于游戏代理(即NPC)的行为方面。我们可以使用Reinforcement Learning(增强学习,简称RL ) 来训练代理,预估某一环境中施行特定行为的价值。一旦训练完成,代理即可以最佳行为模式做出反应,无需通过程序对行为进行显式的编码。
采用老虎机算法的增强学习
RL背后的一个核心概念是价值估计,并据此进行相应动作。在继续深入之前,最好先了解一些术语。
在RL中,实施动作的个体被称为agent(代理),它使用policy(策略)进行动作决策。一个代理通常嵌于一个environment(环境)中,并在任意给定的时刻都处于某个特定的state(状态)。从那个状态,它可以进行一系列actions(动作)。某个给定状态的value(值)指的是处于该状态的最终回报价值。在某个状态执行一个动作可以让代理进入另一个新的状态,获得一个reward(回报),或者同时拥有两者。所有RL代理都在尽可能最大化累计回报。
增强学习循环
多臂老虎机(multi-armed bandit)是RL问题中最简单的一个版本。这个名字由以下这个问题衍生而来:如何使多台老虎机的回报最优化,假定老虎机都具有赚取客户钱的倾向。在本设置中,环境内仅有一个状态,代理能采取n个动作中的一个。每个动作都会立即为代理提供一个回报。代理的目标是找出能提供最多回报的动作。
为了能更好地进行理解,让我们想象一个地牢爬行者游戏中的场景。代理进入一个房间,发现墙边放着一排宝箱。每个宝箱都有一定的几率包含一颗钻石(回报+1)或一个敌人恶魂(回报-1)。
代理的目标就是学习得知哪个宝箱最有可能有钻石。例如从右开始的第三个箱子里有钻石。要找出回报最高的宝箱最自然的方法就是逐一尝试。在代理获得足够的关于这个世界的信息并采取最优化动作之前,大部分RL的工作就是简单的不断试错。上面这个例子用RL的术语来描述就是,“尝试”对应的是采取一系列动作(多次打开每个宝箱),学习对应的是更新每个动作的估计值。一旦我们基本确定值估计,就可以让代理总是选择那个具有最高估计值得宝箱。
三个宝箱,每个都有未知概率包含一颗钻石或一个敌人
这些值估计可以通过一个迭代过程获得。这个过程从最初的一系列估计V(a)开始,并根据每次动作的结果对其进行调整。表达式如下:
其中,α对应我们的学习率,V(a)是给定动作的价值估计,r是采取动作后马上可以获得的回报。
上面的等式很直观,它表明我们将当前的价值估计向获得回报的方向做了一些微调。这样就能确保变化的估计值能更好的反应环境中的真实动态。如此一来,还能确保估计不会变得过大,如果我们仅计算正向结果就可能会发生这种情况。要完成相应代码,我们可以使用一组值估计向量,并通过代理动作对应的索引来引用它们。
https://v.qq.com/txp/iframe/player.html?vid=d0521xgqagh&width=500&height=375&auto=0
三个宝箱上方显示的是代理的值估计(绿色球体),以及真实的概率值(中间的半透明球体)。在这个例子中,三个宝箱的潜在正向回报概率分别是 10%(左),20%(中),80%(右)。随着训练进行,代理的值估计变得越来越精确。
上下文老虎机(Contextual Bandits)
上述的情况缺少了任何真实环境中都有的一个重要方面:它仅有一个状态。在现实以及游戏世界中,一个特定环境可能会处于数十(房子中的房间)到数十亿(一个屏幕上的像素配置)种可能状态中的一种。每个状态都有它们自己独特的动态特性,即动作如何提供新的回报或者允许状态间的迁移。
因此,我们需要对动作,值估计,以及状态设定条件。用符号表示,现在将用Q(s,a)取代V(a)。它的抽象意思是,现在期望获得的回报,是我们所采取的动作以及采取该动作时所处状态的一个函数。
在地牢游戏中,状态的概念使我们可以在不同的房间中拥有不同的宝箱组。每个房间可以有不同的最理想宝箱,因此,代理需要学习在不同房间中采取不同的动作。用代码来实现的话就是,使用一个价值估计矩阵来取代一个简单向量。这个矩阵可以用[state, action]来索引。
探索(Exploring)和利用(Exploiting)
让RL工作还需要一块重要的拼图。在代理习得采取最佳回报动作的策略之前,需要有另一个策略,使它可以充分了解世界,以确保它知道什么是最佳。这引出了一个经典困境,如何平衡探索(exploration)(通过不断试错学习环境的价值结构)和利用(exploitation )(基于环境习得的价值结构采取动作)。有时这两个目标会一致,但通常都会相左。有一系列策略可以平衡这两个目标。下面列出了其中一部分:
一个简单却强大的策略是遵循“optimism in the face of uncertainty”的原则。它的做法是,代理每个动作都从高值估计V(a)开始,这样它就会贪婪地(利用最大值)采取动作,使它将每个动作都至少执行一次。
如果动作没有获得好的回报,就降低对应的价值估计,反之则保持高价值估计,因为该操作可以作为后续好操作的候选。但是仅靠这种自身启发式算法通常仍然不够,因为我们可能需要持续探索某个特定状态以找到一个低频率,却有巨大的回报。
另一个策略是为每个动作的价值估计添加随机噪声,随后根据新的有噪声估计进行贪婪动作。使用这种方式,只要噪声值小于真实最优动作与其他动作间的差异值,就能收敛至最优的价值估计。
现在可以进一步利用值估计自身的特性,将它们进行归一化,依据概率采取动作。这种情况下,如果每个动作的价值估计大致相等,将会以相同概率采取动作。反之,如果一个动作的价值估计要大得多,我们将会更多的选择这个动作。这样就能通过递减选择无回报动作,慢慢将它们淘汰。这是在示例项目中所采用的策略。
结语
有了这篇文章以及相关代码,现在已经可以在Unity中使用多臂与上下文老虎机算法了。但这仅仅是入门而已。在后面的文章中,我们将通过Q-Learning来讲解一个完整的RL问题,并以此为基础,开始用深度神经网络,解决视觉丰富游戏环境中,愈趋复杂的代理行为的学习策略问题。使用这些高级方法,可以训练代理成为我们游戏中的同伴或对手,适用的游戏类型可以是格斗、驾驶、第一人称射击,或甚至实时策略游戏。无需编写任何规则,只需专注于你希望代理达成的状态,而非它如何达成的过程。
后续,我们还会提供一些工具的早期版本,让对使用Unity进行深度RL研究感兴趣的研究者,可以将诸如Tensorflow或PyTorch等框架编写的模型连接到Unity制作的环境中。一起探索可能是未来游戏制作方式的未知领域!
官方活动
活动一:分享Unity技术文章,Unity带你亲临王者荣耀KPL总决赛,倒计时最后2天!
活动二:7月Unity技术路演,Unity技术路演将从沿海深入腹地,即将来到武汉和西安,为当地开发者带来引擎新功能介绍演示和2个不同主题的Workshop内容。报名火热进行中!
推荐阅读
活动 | Unity带你亲临王者荣耀KPL总决赛,领略电竞的魅力
活动 | 7月Unity技术路演 武汉西安双城开发者火热集结!
点击“阅读原文”进入Unity官方中文社区!